import router from '../myProject/src/router/index' // 项目成型后需要单独的登录页面的项目 这个是为了统一登录页面
import axios, { AxiosInstance, AxiosRequestConfig, Method, ResponseType } from 'axios'
import { ElMessage } from 'element-plus'
import useStore from '../store/index'
/** http请求类，集成拦截器处理
 * opts = {
 *     baseURL: string  基础URL地址
 *     timeout: number  超时时长（毫秒）
 *     token: string    每次请求携带的Authorization值
 *     requestHandle function(config):config 请求处理函数，返回处理后的config
 *     responseHandle function(response):response 响应处理函数，返回处理后的response
 * }
 */
interface PendingType {
  url: string;
  method?: Method;
  data?: any;
  responseType?: ResponseType,
  isToken?: boolean
}
interface Params {
  routeParam?: any
  queryParam?: any
}
class Http {
  http: AxiosInstance;
  isToken?: boolean = true; 
  constructor() {
    this.http = axios.create({
      baseURL: process.env.VUE_APP_API_URL,
      timeout: 5000,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
  });

    const pending: any = {}
    const CancelToken = axios.CancelToken
    const removePending = (key: any, isRequest = false) => {
      if (pending[key] && isRequest) {
        pending[key]('请勿重复请求')
        ElMessage({message: '请勿重复请求，请稍等！！', 'type': 'warning'})
      }
      delete pending[key]
    }
    const getRequestIdentify = (config: any, isRequest = false) => {
      let url = config.url
      if (isRequest) {
        url = config.baseURL + config.url.substring(1, config.url.length)
      }
      const arr = ['put', 'post']
      return arr.includes(config.method)
        ? encodeURIComponent(url + JSON.stringify(config.params))
        : encodeURIComponent(config.url + JSON.stringify(config.data))
    }
    // 添加请求拦截器
    this.http.interceptors.request.use((config: AxiosRequestConfig) => {
      // 发送请求之前，拦截重复请求(即当前正在进行的相同请求)
      // const requestData = getRequestIdentify(config, true)
      // removePending(requestData, true)
      // config.cancelToken = new CancelToken((c) => {
      //   pending[requestData] = c
      // })
      const token = useStore.getters.getToken
      config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
      // 在发送请求之前做些什么
      config.params = {
        token
      }
      return config;
    }, function (error) {
      // 对请求错误做些什么
      return Promise.reject(error);
    });

    // 添加响应拦截器
    this.http.interceptors.response.use(response => {
      if(response.status === 200 && response.request.responseType === 'blob') {
        return response.data
      }
      if (response.status === 200 && response.data.code === 0) {
        if(response.data.data) {
          return response.data.data;
        }
        return response.data;
      }
      if(response.status === 200 && response.data.code === 2000) {
        useStore.commit('OUT_LOGIN')
        router.push({ path: "/login" });
      }
      ElMessage({message: response.data.msg, type: 'error'})
      return Promise.reject(response.data)
    }, error => {
      // 对响应错误做点什么
      return error;
    });
  }
 /**
   * 解析URL
   * @param url <string> '/aaa/:id'
   * @param routeParam = <object|map> {id: 1234} 将使用此对象的属性值替换url中的参数
   * @param queryParam = <object|map> {name: 'abc', attr: 'def'} url后面的查询参数
   * @returns {string}
   */
  
  parseUrl(url: string, params: Params) {
    if (params.routeParam) {
        url = url.replace(/:([^/]+)/g, (match, key) => {
            return params.routeParam[key];
        });
    }
    if (params.queryParam) {
        const queryStrings = [];
        for (const i in params.queryParam) {
            queryStrings.push(`${i}=${params.queryParam[i]}`);
        }
        url += '?' + queryStrings.join('&');
    }
    return url;
  }
  /**
   * 请求方法
   * @param url <string> '/aaa/:id'
   * @param param <object|map> {
   *     routeParam = {id: 1234} 将使用此对象的属性值替换url中的参数
   *     queryParam = {name: 'abc', attr: 'def'} url后面的查询参数
   * }
   * 解析后的 url = '/aaa/1234?name=abc&attr=def'
   * @returns {Promise<*>}
   */
  get(types: PendingType, params?: Params) {
    if (params?.routeParam || params?.queryParam) {
      types.url = this.parseUrl(types.url, params);
    }
    this.isToken = types.isToken
    return this.http.get(types.url,{responseType: types.responseType});
  }
  post(types: PendingType, params?: Params) {
    if (params?.routeParam || params?.queryParam) {
      types.url = this.parseUrl(types.url, params);
    }
    this.isToken = types.isToken
    return this.http.post(types.url, types.data, {responseType: types.responseType});
  }
  put(types: PendingType, params?: Params) {
    if (params?.routeParam || params?.queryParam) {
      types.url = this.parseUrl(types.url, params);
    }
    this.isToken = types.isToken
    return this.http.put(types.url, types.data, {responseType: types.responseType});
  }
  patch(types: PendingType, params?: Params) {
    if (params?.routeParam || params?.queryParam) {
      types.url = this.parseUrl(types.url, params);
    }
    this.isToken = types.isToken
    return this.http.patch(types.url, types.data, {responseType: types.responseType});
  }
  delete(types: PendingType, params?: Params) {
    if (params?.routeParam || params?.queryParam) {
      types.url = this.parseUrl(types.url, params);
    }
    this.isToken = types.isToken
    return this.http.delete(types.url, {responseType: types.responseType});
  }
}

export const api = new Http()
